package de.jmda.mview.typeshape;

import javax.lang.model.element.Element;
import javax.swing.Icon;

import de.jmda.mproc.ProcessingUtilities;
import de.jmda.util.gui.awt.graphics.IconProvider;

public abstract class IconFactory
{
	public static Icon getIcon(Element element)
  {
		if (ProcessingUtilities.isClassKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassDefaultFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassDefaultFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassDefaultAbstractStatic();
							}
							else
							{
								return IconProvider.getIconClassDefaultAbstract();
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassDefaultStatic();
							}
							else
							{
								return IconProvider.getIconClassDefault();
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassPrivateFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassPrivateFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassPrivateAbstractStatic();
							}
							else
							{
								return IconProvider.getIconClassPrivateAbstract();
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassPrivateStatic();
							}
							else
							{
								return IconProvider.getIconClassPrivate();
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassProtectedFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassProtectedFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassProtectedAbstractStatic();
							}
							else
							{
								return IconProvider.getIconClassProtectedAbstract();
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassProtectedStatic();
							}
							else
							{
								return IconProvider.getIconClassProtected();
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassPublicFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassPublicFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return IconProvider.getIconClassPublicAbstract();
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassPublicStatic();
							}
							else
							{
								return IconProvider.getIconClassPublic();
							}
						}
					}
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassInnerDefaultFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassInnerDefaultFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerDefaultAbstractStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerDefaultAbstract();
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerDefaultStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerDefault();
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassInnerPrivateFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassInnerPrivateFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerPrivateAbstractStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerPrivateAbstract();
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerPrivateStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerPrivate();
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassInnerProtectedFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassInnerProtectedFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerProtectedAbstractStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerProtectedAbstract();
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerProtectedStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerProtected();
							}
						}
					}
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					if (ProcessingUtilities.isFinal(element))
					{
						if (ProcessingUtilities.isStatic(element))
						{
							return IconProvider.getIconClassInnerPublicFinalStatic();
						}
						else
						{
							return IconProvider.getIconClassInnerPublicFinal();
						}
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerPublicAbstractStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerPublicAbstract();
							}
						}
						else
						{
							if (ProcessingUtilities.isStatic(element))
							{
								return IconProvider.getIconClassInnerPublicStatic();
							}
							else
							{
								return IconProvider.getIconClassInnerPublic();
							}
						}
					}
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isInterfaceKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return IconProvider.getIconInterfaceDefault();
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return IconProvider.getIconInterfacePublic();
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return IconProvider.getIconInterfaceInnerDefault();
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					return IconProvider.getIconInterfaceInnerPublic();
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					return IconProvider.getIconInterfaceInnerPublic();
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return IconProvider.getIconInterfaceInnerPublic();
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isEnumKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return IconProvider.getIconEnumDefault();
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return IconProvider.getIconEnumPublic();
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return IconProvider.getIconEnumInnerDefault();
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					return IconProvider.getIconEnumInnerPublic();
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					return IconProvider.getIconEnumInnerPublic();
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return IconProvider.getIconEnumInnerPublic();
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isAnnotationKind(element))
		{
			Element enclosingElement = element.getEnclosingElement();
			
			if (ProcessingUtilities.isPackageKind(enclosingElement))
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return IconProvider.getIconAnnotationDefault();
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return IconProvider.getIconAnnotationPublic();
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
			else
			{
				if (ProcessingUtilities.isVisibilityDefault(element))
				{
					return IconProvider.getIconAnnotationInnerDefault();
				}
				else if (ProcessingUtilities.isVisibilityProtected(element))
				{
					return IconProvider.getIconAnnotationInnerPublic();
				}
				else if (ProcessingUtilities.isVisibilityPrivate(element))
				{
					return IconProvider.getIconAnnotationInnerPublic();
				}
				else if (ProcessingUtilities.isVisibilityPublic(element))
				{
					return IconProvider.getIconAnnotationInnerPublic();
				}
				else
				{
					throw new IllegalStateException(
							"unexpected visibility for " + element.toString());
				}
			}
		}
		else if (ProcessingUtilities.isFieldKind(element))
		{
			if (ProcessingUtilities.isVisibilityDefault(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconFieldDefaultFinalStatic();
					}
					else
					{
						return IconProvider.getIconFieldDefaultFinal();
					}
				}
				else
				{
					return IconProvider.getIconFieldDefault();
				}
			}
			else if (ProcessingUtilities.isVisibilityPrivate(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconFieldPrivateFinalStatic();
					}
					else
					{
						return IconProvider.getIconFieldPrivateFinal();
					}
				}
				else
				{
					return IconProvider.getIconFieldPrivate();
				}
			}
			else if (ProcessingUtilities.isVisibilityProtected(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconFieldProtectedFinalStatic();
					}
					else
					{
						return IconProvider.getIconFieldProtectedFinal();
					}
				}
				else
				{
					return IconProvider.getIconFieldProtected();
				}
			}
			else if (ProcessingUtilities.isVisibilityPublic(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconFieldPublicFinalStatic();
					}
					else
					{
						return IconProvider.getIconFieldPublicFinal();
					}
				}
				else
				{
					return IconProvider.getIconFieldPublic();
				}
			}
			else
			{
				throw new IllegalStateException(
						"unexpected visibility for " + element.toString());
			}
		}
		else if (ProcessingUtilities.isMethodKind(element))
		{
			if (ProcessingUtilities.isVisibilityDefault(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodDefaultFinalStatic();
					}
					else
					{
						return IconProvider.getIconMethodDefaultFinal();
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodDefaultStatic();
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return IconProvider.getIconMethodDefaultAbstract();
						}
						else
						{
							return IconProvider.getIconMethodDefault();
						}
					}
				}
			}
			else if (ProcessingUtilities.isVisibilityPrivate(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodPrivateFinalStatic();
					}
					else
					{
						return IconProvider.getIconMethodPrivateFinal();
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodPrivateStatic();
					}
					else
					{
						// there are no private abstract methods
						return IconProvider.getIconMethodPrivate();
					}
				}
			}
			else if (ProcessingUtilities.isVisibilityProtected(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodProtectedFinalStatic();
					}
					else
					{
						return IconProvider.getIconMethodProtectedFinal();
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodProtectedStatic();
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return IconProvider.getIconMethodProtectedAbstract();
						}
						else
						{
							return IconProvider.getIconMethodProtected();
						}
					}
				}
			}
			else if (ProcessingUtilities.isVisibilityPublic(element))
			{
				if (ProcessingUtilities.isFinal(element))
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodPublicFinalStatic();
					}
					else
					{
						return IconProvider.getIconMethodPublicFinal();
					}
				}
				else
				{
					if (ProcessingUtilities.isStatic(element))
					{
						return IconProvider.getIconMethodPublicStatic();
					}
					else
					{
						if (ProcessingUtilities.isAbstract(element))
						{
							return IconProvider.getIconMethodPublicAbstract();
						}
						else
						{
							return IconProvider.getIconMethodPublic();
						}
					}
				}
			}
			else
			{
				throw new IllegalStateException(
						"unexpected visibility for " + element.toString());
			}
		}
		else if (ProcessingUtilities.isPackageKind(element))
		{
			return IconProvider.getIconPackage();
		}
		else if (ProcessingUtilities.isEnumConstantKind(element))
		{
			return IconProvider.getIconFieldDefaultFinalStatic();
		}
		else
		{
			throw new IllegalStateException(
					"unexpected element type " + element.toString());
		}
  }
}